package seg;

import geom.Ellipse;
import geom.Point;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import seg.appx.Fit;
import doc.Stroke;

public class MergeAfter {

	private static MergeAfter instance;

	public static MergeAfter get() {
		if (instance == null)
			instance = new MergeAfter();
		return instance;
	}

	private MergeAfter() {
	}

	public Stroke getStroke() {
		return Stroke.get();
	}

	public void merge() {
		Vector<Fit> fits = getStroke().getFits();
		List<Integer> ints = new ArrayList<Integer>();
		int prev = calcSignOf(0);
		for (int i = 1; i < fits.size(); i++) {
			int cur = calcSignOf(i);
			if (prev * cur != 1) {
				ints.add(i-1);
			}
			prev = cur;
		}
//		System.err.println(ints);
		int[] corners = new int[ints.size()];
		int i = 0;
		for (Iterator<Integer> it = ints.iterator(); it.hasNext(); ) {
			corners[i++] = getStroke().getCorners()[it.next()];
		}
		getStroke().setCorners(corners);
	}

	public int calcSignOf(int index) {
		Point sp = startPointOf(index);
		Point ep = endPointOf(index);
		Point mp = midPointOf(index);
		Fit fit = getStroke().getFits().get(index);

		int sign;
		if (fit.isEllipse())
			sign = ((Ellipse) fit).calcSignOf(sp, mp, ep);
		else
			sign = 0;
//		System.out.println("sign of " + index + " is " + sign);
		return sign;
	}

	public Point startPointOf(int index) {
		return getStroke().getPoints()[startPointIndexOf(index)].toPoint();
	}

	public Point endPointOf(int index) {
		return getStroke().getPoints()[endPointIndexOf(index)].toPoint();
	}

	public int startPointIndexOf(int index) {
		if (index == 0)
			return 0;
		else
			return getStroke().getCorners()[index-1];
	}

	public int endPointIndexOf(int index) {
		if (index == getStroke().getFits().size()-1)
			return getStroke().getPoints().length-1;
		else
			return getStroke().getCorners()[index];
	}

	public Point midPointOf(int index) {
		int s = startPointIndexOf(index);
		int e = endPointIndexOf(index);
		return getStroke().getPoints()[(s+e)/2].toPoint();
	}

}
